﻿#ifndef __TEAM_MGR_H__
#define __TEAM_MGR_H__

#include <unordered_map>
#include <list>
#include "../share/object.h"
#include "../share/timer.h"
#include "../share/retcodes.h"
#include "../share/common_singleton.h"
#include "../share/time_module.h"
#include "../../3rd/libjson/json.h"
#include "team_dungeon.h"

#define TEAM_MEMBER_MAX		5
#define TEAM_APPLY_MAX		50
#define TEAM_INVITE_MAX		50

#define TEAM_JOIN_INVITE_MAX	50

class Player;
class CJsonMessageBase;

class CTeamMember
{
public:
	CTeamMember( ) : role_id_( 0 ), status_( 0 ) 
	{
		prepare_ = 0;
	}

	int32_t role_id( ) const { return role_id_; }
	void set_role_id( int32_t role_id ) { role_id_ = role_id; }

	int32_t status( ) { return status_; }
	void set_status( int32_t status ) { status_ = status; }

	const std::string& name()const { return role_name_;}
	void set_name(std::string& name) { role_name_ = name; }
	int32_t role_level() const { return role_level_;}

	void set_prepare(int32_t prepare) { prepare_ = prepare; }
	bool isprepare() { return prepare_ != 0; }
private:
	int32_t role_id_;
	std::string role_name_;
	int32_t role_level_;
	int32_t status_;
	int32_t prepare_;	//是否已经准备0,未准备，1已经准备
};

struct SInvite
{
	int32_t inviter_role_id;
	int32_t inviter_time;
	SInvite()
	{
		inviter_role_id = 0;
		inviter_time = 0;
	}
};

// 队伍目标
class CTeamSet
{
public:
	void CopyFrom(const CTeamSet& teamset)
	{
		activity_id_ = teamset.activity_id();
		is_need_afc_ = teamset.isneed_afc();
		need_afc_ = teamset.need_afc();
		is_need_passwd_ = teamset.isneed_passwd();
		passwd_ = teamset.passwd();
	}
	void TeamSetToJson(Json::Value& teamset_json);
	int32_t activity_id() const { return activity_id_; }
	bool isneed_afc()const { return is_need_afc_; }
	int32_t need_afc() const { return need_afc_; }
	bool isneed_passwd() const { return is_need_passwd_; }
	std::string passwd() const { return passwd_; }

	void set_activity_id(int32_t activity_id) { activity_id_ = activity_id; }
	void set_isneed_afc(bool need) { is_need_afc_ = need; }
	void set_need_afc(int32_t afc) { need_afc_ = afc; }
	void set_isneed_passwd(bool need) { is_need_passwd_ = need; }
	void set_passwd(std::string& passwd) { passwd_ = passwd; }
private:
	int32_t activity_id_;
	bool is_need_afc_;		//是否需要战斗力
	int32_t need_afc_;		//需要的战斗力
	bool is_need_passwd_;	//是否需要密码
	std::string passwd_;	//需要的密码
};

class CTeam 
	: public ::common::CObj
{
public:
	typedef std::vector< CTeamMember >	TEAM_MEMBER_LIST;
	typedef std::vector< int32_t >	TEAM_APPLY_LIST;  //玩家role_id
	typedef std::unordered_map<int32_t, SInvite> TEAM_INVITE_MAP;

	CTeam( );
	~CTeam( );	

	int32_t Clear();

	virtual int32_t Initialize( ) { return Clear( ); };
	virtual int32_t Resume( ) { return Clear( ); };

	void TickUpdate();

	// 加入队伍
	int32_t JoinTeam( Player& player );
		
	// 离开队伍
	int32_t LeaveTeam( int32_t role_id );

	// 解散队伍
	int32_t Dissolve();
	 
	// 是否已经在队伍中
	bool IsInTeam( int32_t role_id );

	// 已经满员
	bool IsFull( );

	// 是否合适的等级
	bool IsRightAfc(int32_t afc);

	bool IsRightPasswd(std::string& passwd);

	// 没有成员
	bool IsEmpty( );

	// 是否是队长
	bool IsCaptain( int32_t role_id ) const;

	//填充队伍信息到PB中
	void BaseData2Json(Json::Value& team_base );

	void TeamData2Json(Json::Value& team_data );

	void Member2Json(int32_t playerid, Json::Value& data);

	//推送队伍基本信息(设置)
	void BroadcastTeamBaseData( );

	void BroadcastTeamSetNotify( );

	void BroadcastDynamicData( int32_t member_id = 0 );

	void BroadcastTeamData( int32_t member_id = 0);

	void SendTeamInitMsg(int32_t role_id);

	void BroadcastMemberLeaveNotice(int32_t role_id);

	void BroadcastMemberJoinNotice(int32_t role_id);

	void BroadcastCaptainAppointNotice( int32_t playerid );

    void BroadcastMessage( int32_t msg_id, Json::Value& msg );

    void BroadcastMessage( int32_t msg_id, const std::string& msg );

	CTeamMember* GetMember( int32_t role_id );
	//获取队伍人数数量
	int32_t GetMemberNum( ) const;

	//清空申请列表
	void ClearApplyList( );

	//加入到申请列表
	void AddApplyList( Player& player );

	//从申请列表中删除
	int32_t RemoveFromApplyList( int32_t role_id );

	//加入邀请列表
	void AddInviteList( int32_t inviter_role_id ,int32_t role_id );
	int32_t RemoveFromInviteList( int32_t role_id );
	bool GetInviteRole( int32_t role_id, SInvite& invite );

	int32_t	captain_id( ) const { return captain_id_; }
	void SetCaptainID( int32_t id );

	const CTeamSet& team_set( ) const { return team_set_; }
	void set_team_set(const CTeamSet& set ) { team_set_.CopyFrom(set); }

	TEAM_MEMBER_LIST& team_member_list( ) { return team_member_list_; }

	void PushApplyListData( );
	void PushApplyOneData(int32_t apply_id);

	CTeamMember* getMember(int32_t role_id);

	CTeamDungeon& team_dungeon() { return team_dungeon_; }

	int32_t getMaxLv() { return max_lv_; }
private:
	//给队长推送申请列表信息
	void ApllyList2Json(Json::Value& applylist, int32_t apply_id );
	
	int32_t captain_id_;				//队长ID
	TEAM_MEMBER_LIST 	team_member_list_;	//队伍玩家列表
	TEAM_APPLY_LIST  	team_apply_list_;	//申请列表
	TEAM_INVITE_MAP		team_invite_map_;	//邀请列表
	int32_t max_lv_;//队伍中最大等级
	
	CTeamSet team_set_;//队伍设置
	int32_t last_update_time_;
	CTeamDungeon team_dungeon_;
};


typedef std::list<int32_t> TINT_LIST;
typedef std::vector<int32_t> TINT_VEC;
struct STeamNum
{
	STeamNum()
	{
		team_id = 0;
		player_num = 0;
		join_time = 0;
		invalid = true;
	}
	int32_t team_id;
	int32_t player_num;
	int32_t join_time;	// 加入匹配时间,暂时不做
	bool invalid;
};
typedef std::vector<STeamNum> TTEAMNUM_VEC;
// 同一个目标的队伍
struct STeamSameAim
{
	typedef std::unordered_map< int32_t, STeamNum > TTEAM_MAP;//<team_id, STeamNum>
	CTeamSet team_set_;
	TTEAM_MAP team_map_;

	void GetSortTeamList(TTEAMNUM_VEC& team_vec);
	void DelTeamByID(int32_t team_id);
	void UpdateTeamNum(int32_t team_id, int32_t player_num);
	void GetNoSortTeamList(TTEAMNUM_VEC& team_vec);
	void AddTeamMatch(int32_t team_id, int32_t player_num);
	
	// 真正删除
	void RemoveInvalidTeam();
};

struct SPlayerMatch
{
	SPlayerMatch()
	{
		role_id = 0;
		join_time = 0;
		invalid = true;
	}
	int32_t role_id;
	int32_t join_time;
	bool invalid;
};
typedef std::vector<SPlayerMatch> TPLAYER_LIST;

// 同一个目标的玩家
struct SPlayerMatchSameAim
{
	CTeamSet team_set_;
	TPLAYER_LIST player_list_;	// 正在匹配中的玩家ID
	// 返回值，弹出玩家的数量
	int32_t PopPlayer( int32_t less_num, int32_t lower_lv, int32_t floor_lv, TINT_LIST& pop_player_list);
	// 返回该队列中玩家数量
	int32_t GetPlayerNum();
	void DelPlayerByID(int32_t role_id);
	void AddPlayerMatch(int32_t role_id);
	bool CheckCanJoinTeam( int32_t less_num, int32_t lower_lv, int32_t floor_lv );

	// 真正删除
	void RemoveInvalidPlayer();
};

// <role_id, team_id>
typedef std::unordered_map<int32_t, int32_t> TTEAM_ROLE_MAP;

class CTeamMgr : public ::common::CSingleton<CTeamMgr>
{
public:
	typedef std::list< STeamSameAim > 			TTeamCanJoinList;
	typedef std::vector< SPlayerMatchSameAim >	TPlayerMatchVec;
	typedef std::list< STeamSameAim >			TMatchTeamList; // 自动匹配状态的队伍

	CTeamMgr( );
	~CTeamMgr( );

	bool Initialize( );
	bool Finalize( );
	
	// 创建队伍
	CTeam* CreateTeam( int32_t& ret_code, Player& player, const CTeamSet& team_set);

	// 加入队伍
	int32_t JoinTeam( Player& player, int32_t team_id );

	// 离开队伍
	int32_t LeaveTeam( int32_t role_id );

	// 踢出队伍
	int32_t KickOutTeam( int32_t captain_role_id,  int32_t ticked_role_id );
		
	// 邀请玩家入队
	int32_t TeamInvite( CTeam& team, int32_t inviter_role_id, int32_t invitee_role_id);

	int32_t TeamInviteMsg( int32_t roleid, int32_t InviteId);
			
	// 队长处理玩家入队申请
	int32_t ReplyTeamApply( int32_t captain_role_id, int32_t apply_id, bool agree );

	// 玩家回复入队邀请
	int32_t ReplyInvite(Player& player, int32_t team_id, bool agree );
	
	// 清空申请列表
	int32_t ClearApplyList( int32_t role_id );

	// 队伍设置
	int32_t TeamSet( int32_t role_id, const CTeamSet& team_set );

	// 队长设置队伍匹配状态
	int32_t TeamSetMatch( int32_t role_id, bool auto_match );

	// 散人自动匹配队伍
	int32_t AutoMatchTeam( int32_t role_id, const CTeamSet& team_aim, bool auto_match, int32_t role_level );

	// 请求队伍列表
	int32_t RequestTeamList( int32_t role_id, int32_t activity_id, Json::Value& teamlist);
	
	// 转让队长
	int32_t AppointCaptain( int32_t captain_id, int32_t role_id );

	int32_t DissolveTeam(CTeam& team);

	//获取队伍对象
	CTeam* GetTeam( int32_t team_id );

	static void OnMsgTeamInfoRequest(Player& player, const CJsonMessageBase& msg);

	//创建队伍请求
	static void OnMsgCreateTeamRequest (Player& player, const CJsonMessageBase& msg);

	//加入队伍请求
	static void OnMsgJoinTeamRequest(Player& player, const CJsonMessageBase& msg);

	//离开队伍请求
	static void OnMsgLeaveTeamRequest(Player& player, const CJsonMessageBase& msg);

	//踢出队伍请求
	static void OnMsgTeamKickOutRequest(Player& player, const CJsonMessageBase& msg);

	//邀请玩家加入队伍请求
	static void OnMsgTeamInviteRequest(Player& player, const CJsonMessageBase& msg);

	//获取邀请列表，目前邀请列表：1，在线好友，2在线公会成员
	static void OnMsgInviteListRequest(Player& player, const CJsonMessageBase& msg);

	//玩家回复入队邀请
	static void OnMsgReplyInviteTeamRequest(Player& player, const CJsonMessageBase& msg);
	static void OnMsgReJectInviteRequest(Player& player, const CJsonMessageBase& msg);

	//队长处理入队申请
	static void OnMsgReplyTeamApplyRequest(Player& player, const CJsonMessageBase& msg);

	//队长一键清空申请列表请求
	static void OnMsgClearTeamApplyRequest(Player& player, const CJsonMessageBase& msg);

	//设置队伍请求
	static void OnMsgTeamSetRequest(Player& player, const CJsonMessageBase& msg);

	//队长设置队伍匹配状态
	static void OnMsgTeamSetMatchRequest(Player& player, const CJsonMessageBase& msg);

	//散人自动匹配队伍
	static void OnMsgAutoMatchTeamRequest(Player& player, const CJsonMessageBase& msg);

	//获取队伍列表请求
	static void OnMsgTeamListRequest(Player& player, const CJsonMessageBase& msg);

	static void OnMsgAppointCaptainRequest(Player& player, const CJsonMessageBase& msg);

	// 布阵请求
	static void OnMsgPrepareFormationRequest(Player& player, const CJsonMessageBase& msg);

	static void OnMsgPrepareRequest(Player& player, const CJsonMessageBase& msg);


	// 组队boss，队长进入副本请求
	static void OnMsgTeamEnterDungeonRequest(Player& player, const CJsonMessageBase& msg);
	int32_t GetAllTeamMemberFightSquare(CTeam& team, int32_t act_id, Json::Value& team_fight_square);
	int32_t CanAllTeamMemberFight(CTeam& team, int32_t actid);

	static void OnMsgMemberDamageReport(Player& player, const CJsonMessageBase& msg);
	static void OnMsgMemberChangeHeroReport(Player& player, const CJsonMessageBase& msg);

	static void OnEventRoleLeaveGame(Player& player);

	STeamSameAim* GetTeamCanJoin( const CTeamSet& team_aim );

	void GetTeamCanJoinByAimID( std::vector<STeamSameAim>& same_aim_vec, const CTeamSet& team_aim );

	SPlayerMatchSameAim* GetPlayerMatchAim( const CTeamSet& team_aim );

	STeamSameAim* GetTeamMatchAim( const CTeamSet& team_aim );

	void TickUpdate( );

	static bool LoopTeam( ::common::CObj& obj, void* param );

	// 匹配逻辑
	void DoTeamMatch(STeamSameAim& team_same_aim, SPlayerMatchSameAim& player_same_aim);
	void DoSinglePlayerMatch(SPlayerMatchSameAim& player_same_aim);
	// 加入可加入列表
	void AddCanJoin( int32_t team_id );
	//从可加入列表中删除
	void DelFromCanJoin( const CTeamSet& team_set, int32_t team_id );
	//从自动匹配玩家列表中删除
	void DelFromMatchPlayer( int32_t role_id );
	//从自动匹配队伍列表中删除
	void DelFromMatchTeam(const CTeamSet& team_set, int32_t team_id );
	bool isSameAim(const CTeamSet& lteam_set, const CTeamSet& rteam_set);


	int32_t GetRoleTeamID(int32_t role_id);
	void AddRoleTeamID(int32_t role_id, int32_t team_id);
	void DelRoleTeamID(int32_t role_id);
private:	
	void SelectedAllTeam(std::vector<int32_t>& selected_team, int32_t role_lv);
	void AddMatchPlayer( const CTeamSet& team_set, int32_t role_id );
	int32_t AddMatchTeam( int32_t team_id );

	TTeamCanJoinList team_can_join_list_; //未满员队伍列表

	TPlayerMatchVec player_match_vec_; //自动匹配状态的玩家

	TMatchTeamList match_team_list_; // 自动匹配状态的队伍

	int32_t last_matchtime_;

	TTEAM_ROLE_MAP team_role_map_;
};

#endif
